﻿using System;
using System.Collections.Generic;
using System.Text;
using Tree.Lifecycle;

namespace Tree.Container
{
    /// <summary>
    /// Object Container.
    /// </summary>
    public interface IObjectContainer : IStartable
    {
        /// <summary>
        /// Dicionatry containing the object colletion.
        /// </summary>
        Dictionary<string, object> Objects { get; }
        
        /// <summary>
        /// Gets a object in the container for the specified Type T.
        /// </summary>
        /// <typeparam name="T">Object Type.</typeparam>
        /// <returns>Object for Type T.</returns>
        T Get<T>() where T : class;

        /// <summary>
        /// Gets a object in the container for the specified Type T. If the object does not exists in the container, the object will be created.
        /// </summary>
        /// <typeparam name="T">Object Type.</typeparam>
        /// <param name="parameters">Parameters to create the object. This must match the object constructor.</param>
        /// <returns>Object for Type T.</returns>
        T Lookup<T>(params object[] parameters) where T : class;

        /// <summary>
        /// Creates a object of the type C and registers in the container under the type T. C must implements T.
        /// </summary>
        /// <typeparam name="T">Object Type.</typeparam>
        /// <typeparam name="C">Object Implementation.</typeparam>
        /// <param name="parameters">Parameters to create the object. This must match the object constructor.</param>
        /// <returns>Object for Type C : T.</returns>
        T Register<T>(params object[] parameters)
            where T : class;

        /// <summary>
        /// Gets a object in the container for the specified Type T. If the object does not exists in the container, the object will be created.
        /// </summary>
        /// <param name="t">Object Type.</param>
        /// <param name="parameters">Parameters to create the object. This must match the object constructor.</param>
        /// <returns>Object for Type T.</returns>
        object Lookup(Type t, params object[] parameters);
    }
}
